package com.codeoss.module.workflow.service.impl;

import java.sql.Timestamp;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.codeoss.framework.context.UserContext;
import com.codeoss.framework.service.impl.BaseService;
import com.codeoss.framework.util.StringUtils;
import com.codeoss.framework.workflow.def.LineDef;
import com.codeoss.framework.workflow.def.StartNodeDef;
import com.codeoss.framework.workflow.def.TaskNodeDef;
import com.codeoss.framework.workflow.def.WorkflowDef;
import com.codeoss.framework.workflow.store.IWorkflowStore;
import com.codeoss.module.workflow.dao.WorkflowTaskMapper;
import com.codeoss.module.workflow.model.WorkflowActivity;
import com.codeoss.module.workflow.model.WorkflowActivityInstance;
import com.codeoss.module.workflow.model.WorkflowComment;
import com.codeoss.module.workflow.model.WorkflowProcess;
import com.codeoss.module.workflow.model.WorkflowTask;
import com.codeoss.module.workflow.model.WorkflowToken;
import com.codeoss.module.workflow.model.WorkflowVariable;
import com.codeoss.module.workflow.service.IWorkflowActivityInstanceService;
import com.codeoss.module.workflow.service.IWorkflowActivityService;
import com.codeoss.module.workflow.service.IWorkflowCommentService;
import com.codeoss.module.workflow.service.IWorkflowProcessService;
import com.codeoss.module.workflow.service.IWorkflowTaskService;
import com.codeoss.module.workflow.service.IWorkflowTokenService;
import com.codeoss.module.workflow.service.IWorkflowVariableService;

@Service
public class WorkflowTaskService extends BaseService<WorkflowTaskMapper, WorkflowTask> implements IWorkflowTaskService {
    @Autowired
    private IWorkflowTokenService workflowTokenService;
    @Autowired
    private IWorkflowActivityInstanceService workflowActivityInstanceService;
    @Autowired
    private IWorkflowProcessService workflowProcessService;
    @Autowired
    private IWorkflowStore workflowStore;
    @Autowired
    private IWorkflowActivityService workflowActivityService;
    @Autowired
    private IWorkflowVariableService workflowVariableService;
    @Autowired
    private IWorkflowCommentService workflowCommentService;
	@Override
	@Transactional
	public void completeTask(Long taskId, String result, String opinion) {
		// TODO Auto-generated method stub
		UserContext userContext=UserContext.getCurrentUserContext();
		
		WorkflowTask workflowTask=getById(taskId);
		
		WorkflowActivityInstance workflowActivityInstance=workflowActivityInstanceService.getById(workflowTask.getWorkflowActivityInstanceId());
		
		WorkflowVariable workflowVariable=new WorkflowVariable();
		workflowVariable.setWorkflowProcessId(workflowActivityInstance.getWorkflowProcessId());
		workflowVariable.setWorkflowTaskId(taskId);
		workflowVariable.setWorkflowTokenId(workflowTask.getWorkflowTokenId());
		workflowVariable.setName("approved");
		workflowVariable.setTextValue(result);
		workflowVariableService.insert(workflowVariable);
		
		if(!StringUtils.isEmpty(opinion)) {
			WorkflowComment workflowComment=new WorkflowComment();
			workflowComment.setWorkflowProcessId(workflowActivityInstance.getWorkflowProcessId());
			workflowComment.setWorkflowTaskId(taskId);
			workflowComment.setResUserId(userContext.getResUserId());
			workflowComment.setComment2(opinion);
			workflowCommentService.insert(workflowComment);
		}
		
		workflowTask.setEndDate(new Timestamp(System.currentTimeMillis()));
		workflowTask.setState("CO");
		update(workflowTask);
		
		WorkflowToken workflowToken=workflowTokenService.getById(workflowTask.getWorkflowTokenId());
		workflowTokenService.signal(workflowToken,result);
	}
	@Override
	@Transactional
	public void back(Long taskId,String opinion) {
		// TODO Auto-generated method stub
		UserContext userContext=UserContext.getCurrentUserContext();
		WorkflowTask workflowTask=getById(taskId);
		workflowTask.setEndDate(new Timestamp(System.currentTimeMillis()));
		workflowTask.setState("CO");
		update(workflowTask);
		
		WorkflowActivityInstance workflowActivityInstance=workflowActivityInstanceService.getById(workflowTask.getWorkflowActivityInstanceId());
		WorkflowActivity workflowActivity=workflowActivityService.getById(workflowActivityInstance.getWorkflowActivityId());
	
		WorkflowProcess workflowProcess=workflowProcessService.getById(workflowActivityInstance.getWorkflowProcessId());
		WorkflowDef workflowDef=workflowStore.get(workflowProcess.getWorkflowWorkflowId());
		
		WorkflowComment workflowComment=new WorkflowComment();
		workflowComment.setWorkflowProcessId(workflowActivityInstance.getWorkflowProcessId());
		workflowComment.setWorkflowTaskId(taskId);
		workflowComment.setResUserId(userContext.getResUserId());
		workflowComment.setComment2(opinion);
		workflowCommentService.insert(workflowComment);
		
		//取消所有草稿的任务
		QueryWrapper<WorkflowTask> taskQuery=new QueryWrapper<WorkflowTask>();
		taskQuery.inSql("workflow_activity_instance_id","select id from workflow_activity_instance where workflow_process_id="+workflowProcess.getId());
		List<WorkflowTask> taskList=list(taskQuery);
		for(int i=0;i<taskList.size();i++) {
			WorkflowTask task=taskList.get(i);
			if(task.getState().equals("DR")) {
				task.setState("CA");
				task.setEndDate(new Timestamp(System.currentTimeMillis()));
				update(task);
			}
		}
		
		TaskNodeDef taskNodeDef=(TaskNodeDef)workflowDef.getNodeDefById(workflowActivity.getNodeId());
		
		StartNodeDef startNodeDef=workflowDef.getStartNode();
		List<LineDef> lineList=workflowDef.getLineList();
		TaskNodeDef firstNodeDef=null;
		for(int i=0;i<lineList.size();i++) { //找到填报任务节点
			LineDef lineDef=lineList.get(i);
			if(lineDef.getFromNodeId().equals(startNodeDef.getId())) {
				firstNodeDef=(TaskNodeDef)lineDef.getToNode();
				break;
			}
		}
		
		LineDef targetLineDef=null;
		for(int i=0;i<lineList.size();i++) {
			LineDef lineDef=lineList.get(i);
			if(lineDef.getFromNodeId().equals(taskNodeDef.getId()) && lineDef.getToNodeId().equals(firstNodeDef.getId())) {
				targetLineDef=lineDef;
			}
		}
		
		WorkflowToken workflowToken=workflowTokenService.getById(workflowTask.getWorkflowTokenId());
		
		if(targetLineDef==null) {
			String name="temp"+Math.random()+System.currentTimeMillis();
			targetLineDef=new LineDef();
			targetLineDef.setName(name);
			targetLineDef.setFromNode(taskNodeDef);
			targetLineDef.setFromNodeId(taskNodeDef.getId());
			targetLineDef.setToNode(firstNodeDef);
			targetLineDef.setToNodeId(firstNodeDef.getId());
			lineList.add(targetLineDef);
			
			workflowTokenService.signal(workflowToken,name,null);
		}else {
			workflowTokenService.signal(workflowToken,targetLineDef.getName(),null);
		}
	}
	@Override
	@Transactional
	public void resubmit(Long taskId) {
		// TODO Auto-generated method stub	
		WorkflowTask workflowTask=getById(taskId);
		workflowTask.setEndDate(new Timestamp(System.currentTimeMillis()));
		workflowTask.setState("CO");
		update(workflowTask);
		
		WorkflowToken workflowToken=workflowTokenService.getById(workflowTask.getWorkflowTokenId());
		workflowTokenService.signal(workflowToken,null);
	}
}